package com.ccrfid.rmc6.resource.device;

import com.ccrfid.rmc6.appconfig.auth.Secured;
import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.device.CardEntity;
import com.ccrfid.rmc6.entity.device.CardView;
import com.ccrfid.rmc6.entity.device.UntreatedCardDto;
import com.ccrfid.rmc6.entity.personnel.PersonnelView;
import com.ccrfid.rmc6.pojo.param.PageParam;
import com.ccrfid.rmc6.repository.search.Criterion;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import com.ccrfid.rmc6.resource.auth.pojo.UserPrincipal;
import com.ccrfid.rmc6.resource.device.pojo.RespData;
import com.ccrfid.rmc6.service.device.CardDownLinkService;
import com.ccrfid.rmc6.service.device.CardService;
import com.ccrfid.rmc6.service.sys.OrgService;
import com.ccrfid.rmc6.util.RegexUtil;
import net.bytebuddy.asm.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Path("/cards")
@Produces(MediaType.APPLICATION_JSON)
public class CardResource {
    private static final Logger logger = LoggerFactory.getLogger(CardResource.class);
    @Autowired
    CardService cardService;
    @Autowired
    private OrgService orgService;
    @Context
    private SecurityContext securityContext;
    @Autowired
    private CardDownLinkService cardDownLinkService;

    @GET
    @Path("search")
    public Page<CardView> getCardInfoPage(@QueryParam("cardNumber") String cardNumber,
                                          @QueryParam("uid") Long uid,
                                          @QueryParam("sn") String sn,
                                          @QueryParam("hexNumber") String hexNumber,
                                          @QueryParam("cardType") Integer cardType,
                                          @QueryParam("onlineStatus") Integer onlineStatus,
                                          @QueryParam("cutoffStatus") Integer cutoffStatus,
                                          @QueryParam("lowpowerStatus") Integer lowpowerStatus,
                                          @QueryParam("bindStatus") Integer bindStatus,
                                          @QueryParam("personnelName") String personnelName,
                                          @QueryParam("nameAcronym") String nameAcronym,
                                          @BeanParam PageParam pageParam) {
        SearchCriteria criteria = SearchCriteria.Builder.create();
        String sql = "select * from v_card where is_enabled is not null ";

        if (cardNumber != null) {
            sql = sql + " and (card_number like '%"+ cardNumber +"%' or hex_number like '%" + cardNumber + "%' or sn like '%" + cardNumber +"%')";
//
//            if (RegexUtil.maybeCardNumber(cardNumber)) {
//                criteria.add(new Criterion("cardNumber", Criterion.Operator.EQ, cardNumber));
//            } else if (RegexUtil.maybeCardHexNumber(cardNumber)) {
//                criteria.add(new Criterion("hexNumber", Criterion.Operator.EQ, cardNumber));
//            } else {
//                criteria.add(new Criterion("sn", Criterion.Operator.LIKE, '%' + cardNumber + '%'));
//            }
        }
        if (uid != null) {
            sql = sql + " and uid = " + uid;

//            criteria.add(new Criterion("uid", Criterion.Operator.EQ, uid));
        }
        if (sn != null) {
            sql = sql + " and (hex_number like '%" + sn +"%' or sn llike  '%"+ sn +"%') ";
//
//            if (RegexUtil.maybeCardHexNumber(sn)) {
//                criteria.add(new Criterion("hexNumber", Criterion.Operator.EQ, sn));
//            } else {
//                criteria.add(new Criterion("sn", Criterion.Operator.LIKE, '%' + sn + '%'));
//            }
        }
        if (hexNumber != null) {
            sql = sql + " and hex_number like '%" + sn +"%'";

//            criteria.add(new Criterion("hexNumber", Criterion.Operator.LIKE, '%' + hexNumber + '%'));
        }
        if (cardType != null) {
            sql = sql + " and card_type = " + cardType;

//            criteria.add(new Criterion("cardType", Criterion.Operator.EQ, cardType));
        }
        if (onlineStatus != null) {
            sql = sql + " and online_status = " + onlineStatus;
//            criteria.add(new Criterion("onlineStatus", Criterion.Operator.EQ, onlineStatus));
        }
        if (cutoffStatus != null) {
            sql = sql + " and cutoff_status = " + cutoffStatus;
//            criteria.add(new Criterion("cutoffStatus", Criterion.Operator.EQ, cutoffStatus));
        }
        if (lowpowerStatus != null) {
            sql = sql + " and lowpower_status = " + lowpowerStatus;

//            criteria.add(new Criterion("lowpowerStatus", Criterion.Operator.EQ, lowpowerStatus));
        }
        if (bindStatus != null) {
            sql = sql + " and bind_status = " + bindStatus;
//            criteria.add(new Criterion("bindStatus", Criterion.Operator.EQ, bindStatus));
        }
        if (!StringUtils.isEmpty(personnelName)) {
            if (RegexUtil.maybeNameAcronym(personnelName)) {
                sql = sql + " and name_acronym like '%" + personnelName + "%'";

//                criteria.add(new Criterion("nameAcronym", Criterion.Operator.LIKE, personnelName + '%'));
            } else {
                sql = sql + " and personnel_name like '%" + personnelName + "%'";
//                criteria.add(new Criterion("personnelName", Criterion.Operator.LIKE, '%' + personnelName + '%'));
            }
        }
        if (!StringUtils.isEmpty(nameAcronym)) {
            sql = sql + " and name_acronym like '%" + nameAcronym + "%'";
//            criteria.add(new Criterion("nameAcronym", Criterion.Operator.LIKE, '%' + nameAcronym + '%'));
        }

        PageRequest pageRequest;
        if (pageParam.getOrders() != null && pageParam.getOrders().size() > 0) {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize(), Sort.by(pageParam.getOrders()));
        } else {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize());
        }
//        Page<CardView> page = cardService.getCardInfoPage(criteria, pageRequest);
        return cardService.getCardInfo(sql, pageRequest);
//        return page;
    }

    @GET
    @Path("{id}")
    public CardEntity getCardById(@PathParam("id") Long cardId) {
        CardEntity cardEntity = cardService.getCardById(cardId);
        return cardEntity;
    }

    @PUT
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public CardEntity updateCard(@PathParam("id") Long cardId, CardEntity entity) throws AppException {
        CardEntity cardEntity = cardService.updateCard(cardId, entity);
        return cardEntity;
    }

    @GET
    @Path("{id}/personnel")
    public PersonnelView getCardBindPersonnelInfo(@PathParam("id") Long cardId) {
        PersonnelView personnelView = cardService.getCardBindPersonnelInfo(cardId);
        return personnelView;
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public CardEntity createCard(CardEntity entity) throws AppException {
        CardEntity cardEntity = cardService.createCard(entity);
        return cardEntity;
    }

    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
    public int deleteCards(List<Long> idList) throws AppException {
        if (idList == null) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.param_is_null.getCode(), CustomErrors.param_is_null.getReason(), "");
        }
        return cardService.deleteCards(idList);
    }

//    /**
//     * 异常标签数量统计
//     *
//     * @return
//     */
//    @Secured
//    @GET
//    @Path("card-statistic")
//    public CardStatisticDto getCardStatistic() {
//        return cardService.getCardStatistic();
//    }

    /**
     * 异常标签详情
     *
     * @return
     */
    @Secured
    @GET
    @Path("untreated_cards")
    public Page<UntreatedCardDto> getUntreatedCards(@QueryParam("onlineStatus") Integer onlineStatus,
                                                    @QueryParam("cutoffStatus") Integer cutoffStatus,
                                                    @QueryParam("lowpowerStatus") Integer lowpowerStatus,
                                                    @QueryParam("pos") Integer pos,
                                                    @BeanParam PageParam pageParam) {
        Map<String, Integer> param = new HashMap<>(16);
        if (onlineStatus != null) {
            param.put("onlineStatus", onlineStatus);
        }
        if (cutoffStatus != null) {
            param.put("cutoffStatus", cutoffStatus);
        }
        if (lowpowerStatus != null) {
            param.put("lowpowerStatus", lowpowerStatus);
        }
        if (pos != null) {
            param.put("pos", pos);
        }
        PageRequest pageRequest;
        if (pageParam.getOrders() != null && pageParam.getOrders().size() > 0) {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize(), Sort.by(pageParam.getOrders()));
        } else {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize());
        }
        return cardService.getCardStatisticPage(param, pageRequest);
    }



    @Secured
    @GET
    @Path("search-huaihua")
    public Page<CardView> getCardInfoHuaihuaPage(@QueryParam("cardNumber") String cardNumber,
                                          @QueryParam("uid") Long uid,
                                          @QueryParam("sn") String sn,
                                          @QueryParam("hexNumber") String hexNumber,
                                          @QueryParam("cardType") Integer cardType,
                                          @QueryParam("onlineStatus") Integer onlineStatus,
                                          @QueryParam("cutoffStatus") Integer cutoffStatus,
                                          @QueryParam("lowpowerStatus") Integer lowpowerStatus,
                                          @QueryParam("bindStatus") Integer bindStatus,
                                          @QueryParam("personnelName") String personnelName,
                                          @QueryParam("nameAcronym") String nameAcronym,
                                          @BeanParam PageParam pageParam) {

        UserPrincipal userPrincipal = (UserPrincipal) securityContext.getUserPrincipal();
        Long orgId = userPrincipal.getOrgId();
        List<Long> orgIdList = orgService.getSubOrgIdList(orgId);
        String sql = "select * from v_card where org_id in :orgIdList ";
        if (cardNumber != null) {
            sql = sql + " and (card_number like '%"+ cardNumber +"%' or hex_number like '%" + cardNumber + "%' or sn like '%" + cardNumber +"%')";
        }
        if (uid != null) {
            sql = sql + " and uid = " + uid;
        }
        if (sn != null) {
            sql = sql + " and (hex_number like '%" + sn +"%' or sn llike  '%"+ sn +"%') ";
        }
        if (hexNumber != null) {
            sql = sql + " and hex_number like '%" + sn +"%'";
        }
        if (cardType != null) {
            sql = sql + " and card_type = " + cardType;
        }
        if (onlineStatus != null) {
            sql = sql + " and online_status = " + onlineStatus;
        }
        if (cutoffStatus != null) {
            sql = sql + " and cutoff_status = " + cutoffStatus;
        }
        if (lowpowerStatus != null) {
            sql = sql + " and lowpower_status = " + lowpowerStatus;

        }
        if (bindStatus != null) {
            sql = sql + " and bind_status = " + bindStatus;
        }
        if (!StringUtils.isEmpty(personnelName)) {
            if (RegexUtil.maybeNameAcronym(personnelName)) {
                sql = sql + " and name_acronym like '%" + personnelName + "%'";

            } else {
                sql = sql + " and personnel_name like '%" + personnelName + "%'";
            }
        }
        if (!StringUtils.isEmpty(nameAcronym)) {
            sql = sql + " and name_acronym like '%" + nameAcronym + "%'";
        }

        PageRequest pageRequest;
        if (pageParam.getOrders() != null && pageParam.getOrders().size() > 0) {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize(), Sort.by(pageParam.getOrders()));
        } else {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize());
        }
        return cardService.getCardInfoHuaihua(sql,orgIdList, pageRequest);
    }

    //下发水墨卡片用户信息
    @GET
    @Secured
    @Path("downLink-user-info")
    @Consumes(MediaType.APPLICATION_JSON)
    public RespData beaconMessage(@QueryParam("personnelId") Long personnelId) {
        return cardDownLinkService.downLinkInfo(personnelId);
    }

    //校时
    @GET
    @Secured
    @Path("timing")
    @Consumes(MediaType.APPLICATION_JSON)
    public void cardTiming(@QueryParam("tag") String tag) {
         cardDownLinkService.timing(tag);
    }
}
